package bankingSystemServer;

import java.io.ObjectOutputStream;
import java.net.ServerSocket;

/**
 * an abstract server
 */
public abstract class Server {
	public static int LISTENING_PORT = 49999;
	private boolean serverRunning;
	private AccountDatabase accounts;
	protected UserDatabase users;
	private ServerSocket socket;

	/**
	 * creates a new Server
	 */
	public Server() {
		accounts = new AccountDatabase();
		users = new UserDatabase();
	}

	public void addUser(User user) {
		users.add(user);
	}

	/**
	 * run the operations a server performs
	 */
	public void run() {
		serverRunning = true;
		System.out.println("Server started...");
		try {
			socket = new ServerSocket(LISTENING_PORT);
			while (serverRunning) {
				System.out.println("Listening for a connection...");
				new ServerListeningThread(socket.accept(), this).start();
				System.out.println("Accepted a client.");
			}
			socket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Attempts to login a user.
	 * 
	 * @param username
	 * @param password
	 * @return Returns true if successful.
	 */
	public boolean login(String username, String password) {
		System.out.println("Searching for user " + username + " in database");
		return users.userExists(new User(username, password));
	}
	
	public String getUserStrings() {
		return users.toString();
	}

	/**
	 * Handles the request from client
	 * 
	 * @param request
	 *            the request from client
	 * @param fromSocket
	 *            the socket the client is from
	 * @param thread
	 *            the thread from which the request was received
	 */
	abstract public void receiveMessage(Object request,
			ObjectOutputStream objectOutputStream, ServerListeningThread thread);
	
	public boolean addAccount(String customerName, String accountNumber, int balance){
		User user = users.getUser(customerName);
		if(user == null){
			return false;
		}
		if(user instanceof Customer){
			Customer customer = (Customer)user;
			Account newAccount = new Account(accountNumber, customer, balance);
			customer.addAccount(newAccount);
			accounts.addAccount(newAccount);
		}
		return true;
	}

}
